<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "./mixins/resize";
import lodash from "lodash";

export default {
  mixins: [resize],
  props: {
    className: { type: String, default: "chart" },
    width: { type: String, default: "100%" },
    height: { type: String, default: "350px" },
    chartData: { type: Object, required: true },
    showType: { type: Boolean, default: false },
    title: { type: String, default: "" }
  },
  data() {
    return {
      chart: null,
      showChartData: { tradingDay: [], pnlToday: [], pnlHold: [], pnlTrade: [] },
      pnlAccuTotal: [],
      pnlAccuHold: [],
      pnlAccuTrade: [],
      dataZoomFunc: null,
      start: 0,
      end: 50
    };
  },
  watch: {
    chartData: { deep: true, handler() { this.setOptions(); } },
    showType: { deep: true, handler() { this.resetData(); } }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },
  beforeDestroy() {
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el, "macarons");
      this.setOptions(this.chartData);
      const that = this;
      this.chart.on("datazoom", function(params) {
        that.handleDataZoom(params);
      });
    },
    setOptions() {
      this.showChartData = JSON.parse(JSON.stringify(this.chartData));
      if (this.showChartData.gridTime.length !== 0) {
        this.pnlAccuTotal[0] = this.showChartData.pnlToday[0];
        this.pnlAccuHold[0] = this.showChartData.pnlHold[0];
        this.pnlAccuTrade[0] = this.showChartData.pnlTrade[0];

        for (let i = 1; i < this.showChartData.gridTime.length; i++) {
          this.pnlAccuTotal[i] = this.showChartData.pnlToday[i] + this.pnlAccuTotal[i - 1];
          this.pnlAccuHold[i] = this.showChartData.pnlHold[i] + this.pnlAccuHold[i - 1];
          this.pnlAccuTrade[i] = this.showChartData.pnlTrade[i] + this.pnlAccuTrade[i - 1];
        }
      }

      this.chart.setOption({
        title: { left: "left", text: this.title },
        tooltip: { trigger: "axis", axisPointer: { type: "shadow" }},
        grid: { left: "2%", right: "2%", bottom: "3%", containLabel: true },
        xAxis: [{ type: "category", data: this.showChartData.gridTime, boundaryGap: true }],
        yAxis: [{ type: "value", minInterval: 1, boundaryGap: [0, 0.1] }],
        legend: { left: "right", data: ["pnlToday", "pnlHold", "pnlTrade"] },
        series: [
          { name: "pnlToday", type: "bar", data: this.showChartData.pnlToday },
          { name: "pnlHold", type: "bar", data: this.showChartData.pnlHold },
          { name: "pnlTrade", type: "bar", data: this.showChartData.pnlTrade }
        ],
        dataZoom: [
          { show: true, realtime: true, start: 0, end: 50 },
          { type: "inside", realtime: true, start: 0, end: 50, zoomOnMouseWheel: false }
        ]
      });
      this.chart.dispatchAction({ type: "dataZoom", start: 0, end: 50 });
    },
    resetData() {
      this.showChartData = JSON.parse(JSON.stringify(this.chartData));
      this.chart.setOption({
        xAxis: [{ data: this.showChartData.gridTime }],
        series: [
          { data: this.showChartData.pnlToday },
          { data: this.showChartData.pnlHold },
          { data: this.showChartData.pnlTrade }
        ]
        // ,
        // dataZoom: [
        //   { show: true, realtime: true, start: 0, end: 50 },
        //   { type: 'inside', realtime: true, start: 0, end: 50 }
        // ]
      });
      // this.chart.dispatchAction({ type: 'dataZoom', start: 0, end: 50 })
      this.handleDataZoom({ start: this.start, end: this.end });
    },
    updateOptions(startPos, endPos, startIndex, endIndex) {
      this.showChartData = JSON.parse(JSON.stringify(this.chartData));
      const rangeData = { gridTime: [], pnlToday: [], pnlHold: [], pnlTrade: [] };

      for (let m = startIndex; m <= endIndex; m++) {
        if (startIndex === 0) {
          this.showChartData.pnlToday[m] = this.pnlAccuTotal[m];
          this.showChartData.pnlHold[m] = this.pnlAccuHold[m];
          this.showChartData.pnlTrade[m] = this.pnlAccuTrade[m];
        } else {
          this.showChartData.pnlToday[m] = this.pnlAccuTotal[m] - this.pnlAccuTotal[startIndex - 1];
          this.showChartData.pnlHold[m] = this.pnlAccuHold[m] - this.pnlAccuHold[startIndex - 1];
          this.showChartData.pnlTrade[m] = this.pnlAccuTrade[m] - this.pnlAccuTrade[startIndex - 1];
        }
        rangeData.gridTime.push(this.showChartData.gridTime[m]);
        rangeData.pnlToday.push(this.showChartData.pnlToday[m]);
        rangeData.pnlHold.push(this.showChartData.pnlHold[m]);
        rangeData.pnlTrade.push(this.showChartData.pnlTrade[m]);
      }

      this.chart.setOption({
        xAxis: [{ data: this.showChartData.gridTime }],
        series: [
          { data: this.showChartData.pnlToday },
          { data: this.showChartData.pnlHold },
          { data: this.showChartData.pnlTrade }
        ],
        dataZoom: [
          { show: true, realtime: true, start: startPos, end: endPos },
          { type: "inside", realtime: true, start: startPos, end: endPos }
        ]
      });

      this.$emit("barChartRangeChange", rangeData);
    },
    handleDataZoom: lodash.debounce(function(param) {
      this.start = param.start;
      this.end = param.end;
      const length = this.showChartData.gridTime.length;
      const startIndex = Math.floor(param.start / 100 * length);
      const endIndex = Math.ceil(param.end / 100 * length);
      if (!this.showType) {
        if (length !== undefined && length > 0) {
          this.updateOptions(param.start, param.end, startIndex, endIndex);
        }
      } else {
        const rangeData = { gridTime: [], pnlToday: [], pnlHold: [], pnlTrade: [] };
        for (let m = startIndex; m <= endIndex; m++) {
          rangeData.gridTime.push(this.showChartData.gridTime[m]);
          rangeData.pnlToday.push(this.showChartData.pnlToday[m]);
          rangeData.pnlHold.push(this.showChartData.pnlHold[m]);
          rangeData.pnlTrade.push(this.showChartData.pnlTrade[m]);
        }
        this.$emit("barChartRangeChange", rangeData);
      }
    }, 300)
  }
};
</script>
